/***************************************************************************
 *   Copyright (C) 2007 by crackedmind                                     *
 *   digital.stream.of.mind@gmail.com                                      *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU Library General Public License as       *
 *   published by the Free Software Foundation; either version 2 of the    *
 *   License, or (at your option) any later version.                       *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU Library General Public     *
 *   License along with this program; if not, write to the                 *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#ifndef SHAREDLIBRARY_HPP_INCLUDED
#define SHAREDLIBRARY_HPP_INCLUDED

#if defined PLATFORM_WIN32
    typedef HMODULE SL_handle;
#elif defined PLATFORM_LINUX
    typedef void*   SL_handle;
#endif

#define SL_INTERFACE_VERSION    0x02

enum SL_Flags
{
    SL_LAZY       = 0x00000001,     // resolve undefined symbols at first use
                                    // (only works on some Unix versions)
    SL_NOW        = 0x00000002,     // resolve undefined symbols on load
                                    // (default, always the case under Win32)
    SL_GLOBAL     = 0x00000004,     // export extern symbols to subsequently
                                    // loaded libs.
    SL_LOCAL      = 0x00000008,     //
    SL_DEFAULT    = SL_NOW          // default flags correspond to Win32
};

class SharedLibrary
{
private:
    SL_handle _handle;

    char * _error;
    const char * _libname;

    bool _isLoaded;
    bool _isAutoUnload;

#if defined PLATFORM_WIN32
    char _name[MAX_PATH];
    char _path[MAX_PATH];
#elif defined PLATFORM_LINUX
    char _name[PATH_MAX];
    char _path[PATH_MAX];
#endif

private:
    SharedLibrary& operator=(const SharedLibrary&);
    SharedLibrary(const SharedLibrary&);
    SharedLibrary();
public:
    SharedLibrary ( const char *library) :	_handle(NULL), _error(NULL),
											_libname(library), _isLoaded(true),
                                            _isAutoUnload(true)
    {
#if defined PLATFORM_WIN32
        memset(_name, 0, MAX_PATH);
        memset(_path, 0, MAX_PATH);
#elif defined PLATFORM_LINUX
        memset(_name, 0, PATH_MAX);
        memset(_path, 0, PATH_MAX);
#endif
    }

    ~SharedLibrary();

    bool load(SL_Flags flags=SL_DEFAULT);
    bool unload();

    bool isLoaded () const
    {
        return _isLoaded;
    }

    bool autoUnload () const
    {
        return _isAutoUnload;
    }

    void setAutoUnload ( bool isAutoUnload )
    {
        _isAutoUnload = isAutoUnload;
    }

    const char * name() const
    {
        return _name;
    }

    const char * path() const
    {
        return _path;
    }

    void * symbol ( const char* proc );

    const char* error();
};

#endif // SHAREDLIBRARY_HPP_INCLUDED
